#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#include "lib.h"
#include "tracksql.h"
#include "smtp.h"

#include "odbc.h"
#include "missinggamenums.h"

#include "opts.h"


TrackSQL::TrackSQL(const String& dsn, const String& dblogin, const String& dbpasswd)
{
	this->dbdsn = dsn;
	this->dblogin = dblogin;
	this->dbpasswd = dbpasswd;

	pool = new ODBCPool();
	if (!pool)
		return;

	if (!pool->init())
	{
		delete pool;
		pool = (ODBCPool*)0;
		return;
	}
}

TrackSQL::~TrackSQL()
{
	delete pool;
	pool = (ODBCPool*)0;
}

bool8
TrackSQL::initOK()
{
	return (bool8)(pool != (ODBCPool*)0);
}

ODBCConnection*
TrackSQL::getConn()
{
	if (pool)
		return pool->open(dbdsn, dblogin, dbpasswd);

	return (ODBCConnection*)0;
}


int32
TrackSQL::putLobbyRequest(int32 casinoID, const PID& pid,int reqtype)
{

ODBCConnection* conn;
	ODBCQuery* query;
	bool8 ok = false;

	conn = getConn();
	if (!conn)
		return NoConnection;

	query = conn->query();

	if (query)
	{
		query->define("exec pub_bank_InsertDLClientRequest ");
		query->addParam(casinoID);
		query->addParam(pid);
		query->addParam((int32)reqtype);
		ok=query->exec();
		delete query;
	}
	delete conn;

	return ok ? NoError : ExecFailed;



}

int32
TrackSQL::getLobbyRequest(int32 casinoID, const PID& pid,String& strResult,int type)
{
	ODBCConnection* conn;
	ODBCQuery* query;
	bool8 ok = false;
	String strIn;

	conn = getConn();
	if (!conn)
		return NoConnection;

	query = conn->query();

	if (query)
	{
		query->define("exec pub_bank_GetDLClientRequest ");
		query->addParam(casinoID);
		query->addParam(pid);
		query->addParam((int32)type);
		
		if (query->exec())
		{
			while (query->getRow())
			{
				if (query->getData(1, strResult))
					ok = true;
			}
		}
		delete query;
	}
	delete conn;

	DEBUGMSG(("TrackSQL::getLobbyRequest()Got value: '%S'",(const uint16*)strResult));
			
	return ok ? NoError : ExecFailed;
}

int32
TrackSQL::getBalance(int32 casinoID, const PID& pid, bool8 forMoney,
	int32* balance, int32* comp, int32 *bonusBalance, int32 *playthroughBalance)
{
	ODBCConnection* conn;
	ODBCQuery* query;
	bool8 ok = false;

	conn = getConn();
	if (!conn)
		return NoConnection;

	query = conn->query();

	if (query)
	{
		query->define("exec pub_bank_GetAccountBalance ");
		query->addParam(casinoID);
		query->addParam(pid);
		query->addParam(forMoney);

		if (query->exec())
		{
			while (query->getRow())
			{
				if (query->getData(1, balance, ODBCQuery::MONEY) &&
					query->getData(2, comp))
					ok = true;

				if ((query->numCols() > 2) && bonusBalance)
					if (!query->getData(3, bonusBalance, ODBCQuery::MONEY))
						ok = false;

				if ((query->numCols() > 3) && playthroughBalance)
					if (!query->getData(4, playthroughBalance, ODBCQuery::MONEY))
						ok = false;

			}
		}
		delete query;
	}
	delete conn;

	return ok ? NoError : ExecFailed;
}

int32
TrackSQL::adjustBalance(int32 casinoID, const PID& pid, bool8 forMoney,
	int32 amount, int32* newBalance, int32* comp)
{
	ODBCConnection* conn;
	ODBCQuery* query;
	bool8 ok = false;

	if (amount != 0)
	{
		conn = getConn();
		if (!conn)
			return NoConnection;

		query = conn->query();

		if (query)
		{
			query->define("exec pub_bank_AdjustBalance ");
			query->addParam(casinoID);
			query->addParam(pid);
			query->addParam(forMoney);
			query->addParam(amount, ODBCQuery::MONEY);

			if (query->exec())
			{
				int32 success;

				while (query->getRow())
				{
					if (query->getData(1, &success) &&
						success &&
						query->getData(2, newBalance, ODBCQuery::MONEY) &&
						query->getData(3, comp))
						ok = true;
				}
			}
			delete query;
		}

		delete conn;

		return ok ? NoError : ExecFailed;
	}
	else
		return getBalance(casinoID, pid, forMoney, newBalance, comp);
}

int32
TrackSQL::getPlayerLimits(const PID& pid, int32 gameId, uint8 machId,
	int32* minBet, int32* maxBet, int32* compFactor)
{
	ODBCConnection* conn;
	ODBCQuery* query;
	bool8 ok = false;

	conn = getConn();
	if (!conn)
		return NoConnection;

	query = conn->query();

	if (query)
	{
		query->define("exec pub_lim_getPlayerLimits ");
		query->addParam(pid);
		query->addParam(gameId);
		query->addParam(machId, ODBCQuery::BINARY);

		if (query->exec())
		{
			while (query->getRow())
			{
				if (query->getData(4, minBet, ODBCQuery::MONEY) &&
					query->getData(5, maxBet, ODBCQuery::MONEY) &&
					query->getData(6, compFactor))
					ok = true;
			}
		}
		delete query;
	}
	delete conn;

	return ok ? isGameEnabled(gameId,machId) : ExecFailed;
}

int32
TrackSQL::validateLogin(const String& login, SESSIONID sessionID, PID& pid, int32 token, bool8* correcttoken)
{
	ODBCConnection* conn;
	ODBCQuery* query;
	int32 logged_in = 0;  // logged out by default
	bool8 ok = false;
	bool8 bit = 0;
	int8 logout_type = 0;

	if (correcttoken)
		*correcttoken = false;

	conn = getConn();
	if (!conn)
		return NoConnection;

	query = conn->query();
	if (query)
	{
		query->define("exec pub_ValidateLogin ");
		query->addParam(login);
		query->addParam(token);

		if (query->exec())
		{
			uint8 i = 0;

			while (query->getRow())
			{
				if (i++ == 0 &&
					query->getData(1, &logged_in) &&
					query->getData(2, sessionID, MAXSESSIONIDLEN) &&
					query->getData(3, &bit) &&
					query->getData(4, pid) &&
					query->getData(6, &logout_type))
				{
					ok = true;

					if (correcttoken)
						*correcttoken = bit;
				}
			}
		}
		delete query;
	}
	delete conn;

	if(ok)
	{
		if(logged_in)
			return NoError;

		else
		{
			// see the PlayerLogoutTypes table
			if (logout_type == 1) // kharmon.  11-29-07.  #20435.  Need to handle case where player logged out, but for some reason they're still playing!
				return TrackSQL::NormalLogout;

			// [AO 2008-01-11] Logged out by logging in from a different client
			else if (logout_type == 2 || logout_type == 4)
				return TrackSQL::AdminLogout;

			else if (logout_type == 3)
				return TrackSQL::AutoLogout;
		}
	}

	return ExecFailed;
}

int32
TrackSQL::validateSession(const PID& pid, SESSIONID sessionID)
{
	// CSN-11525: if no session, no need for database call. Just return not logged
	if (strlen(sessionID) == 0)
	{
		return TrackSQL::NormalLogout;
	}

	ODBCConnection* conn;
	ODBCQuery* query;
	int32 logged_in = 0;  // logged out by default
	bool8 ok = false;
	int8 logout_type = 0;

	conn = getConn();
	if (!conn)
		return NoConnection;

	query = conn->query();
	if (query)
	{
		query->define("exec pub_ValidateSession ");
		query->addParam(pid);
		query->addParam(sessionID);

		if (query->exec())
		{
			uint8 i = 0;

			while (query->getRow())
			{
				if (i++ == 0 &&
					query->getData(1, &logged_in) &&
					query->getData(2, &logout_type))
				{
					ok = true;
				}
			}
		}
		delete query;
	}
	delete conn;

	if(ok)
	{
		if(logged_in)
			return NoError;

		else
		{
			// see the PlayerLogoutTypes table
			if (logout_type == 1) // kharmon.  11-29-07.  #20435.  Need to handle case where player logged out, but for some reason they're still playing!
				return TrackSQL::NormalLogout;

			// [AO 2008-01-11] Logged out by logging in from a different client
			else if (logout_type == 2 || logout_type == 4)
				return TrackSQL::AdminLogout;

			else if (logout_type == 3)
				return TrackSQL::AutoLogout;
		}
	}

	return ExecFailed;
}

int32
TrackSQL::getLocale( localCurrency *localCurr, int32 *chipValues )
{
	ODBCConnection* conn;
	ODBCQuery* query;

	conn = getConn();
	if (!conn)	
		return NoConnection;

	bool8 ok = false;

	query = conn->query();
	if (query)
	{
		// get Chip Values for this Currency

		query->define("exec pub_getLocale");
		if (query->exec())
		{
			while (query->getRow())
			{
				int32 last, chipsL;
				char  *p, chips[MAX_CHIPS_STR+1];
				ok = query->getData(1, localCurr->int_curr_symbol) &&
					 query->getData(2, localCurr->currency_symbol) &&
					 query->getData(3, localCurr->decimal_sep) &&
					 query->getData(4, localCurr->thousands_sep) &&
					 query->getData(5, &localCurr->grouping ) &&
					 query->getData(6, &localCurr->frac_digits) &&
					 query->getData(7, &localCurr->cs_precedes) &&
					 query->getData(8, &localCurr->sep_by_space) &&
					 query->getData(9, (uint8*)chips, MAX_CHIPS_STR, &chipsL) &&                     
                     query->getData(11, localCurr->subcurrency_symbol) &&       // kharmon.  11-18-05.  #7145.  Added subcurrency info to login response.
					 query->getData(12, &localCurr->scs_precedes) &&
					 query->getData(13, &localCurr->scs_sep_by_space);

				if (ok && chipValues)
				{
					int8  i;

					*(chips+chipsL)=0;
					for(  last=0, i=0, p=strtok(chips,",");  p && i<MAX_CHIPS; p=strtok(NULL,","),i++ )
					{
						int v = atoi(p);
						if( v<=last || v<=0 ) { *chipValues =-1; break; }
						*(chipValues+i) = v;
					}
				}
			}
		}

		delete query;
	}
	delete conn;
		
	return ok ? NoError : ExecFailed;
}

String
TrackSQL::getEmailMsg(	int32 casinoId,
						int32 skinId,
						const PID& pid,
						int32 emailId,
						String& nameFrom,
						String& emailFrom,
						String& emailTo,
						String& sBccEmailAddress,
						String& subject,
						bool8* bEmailAsHtml)
{
	ODBCConnection* conn;
	ODBCQuery* query;
	String sResult;

    nameFrom.empty();
    emailFrom.empty();
    emailTo.empty();
    sBccEmailAddress.empty();
    subject.empty();

	conn = getConn();
	if (!conn)
    {
		return sResult;
    }

	query = conn->query();
	if (query)
	{
		query->define("exec pub_GetEMailResponse ");
		query->addParam(emailId);
		query->addParam(casinoId);
		query->addParam(pid);
		query->addParam(skinId);

		if (query->exec())
		{
			// length
			//
			if (query->getRow())
			{
				if (query->numCols() >= 7)
				{
					query->getData(2, emailTo);
					query->getData(3, emailFrom);
					query->getData(4, nameFrom);
					query->getData(5, subject);
					query->getData(6, sBccEmailAddress);
					query->getData(7, bEmailAsHtml);
				}
			}

			// text
			//
			if (query->getRow())
			{
                query->getData( 1, &sResult );
			}
		}

		// take care of errors
		//
        if( !sResult.isEmpty() && ((emailTo.find( "@" )   == String::NPOS) ||
                                   (emailFrom.find( "@" ) == String::NPOS)    ) )
		{
            sResult.empty();
        }

		delete query;
	}
	delete conn;

	return sResult;
}




// Pass NULL for conn and it will open a connection for you
bool8
TrackSQL::getSystemEmailRouting(ODBCConnection* conn, int32 msgID,
							String& nameFrom, String& emailFrom, String& emailTo, String& subject)
{
	ODBCConnection* localConn;
	ODBCQuery* query;
	bool8 bCloseConn = false;
	bool8 bEnabled = false;

	if (conn)
    {
		localConn = conn;
    }
	else
	{
		localConn = getConn();
		if (!localConn)
        {
			return false;
        }

		bCloseConn = true;
	}

    nameFrom.empty();
    emailFrom.empty();
    emailTo.empty();
    subject.empty();

	query = localConn->query();
	if (query)
	{
		query->define("exec pub_GetSystemNotification ");
		query->addParam(msgID);

		if (query->exec())
		{
			if (query->getRow())
			{
				bEnabled &= query->getData(1, emailTo);
				bEnabled &= query->getData(2, emailFrom);
				bEnabled &= query->getData(3, nameFrom);
				bEnabled &= query->getData(4, subject);
				bEnabled &= query->getData(5, &bEnabled);
			}
		}

		delete query;
	}

	if (bCloseConn)
    {
		delete localConn;
    }

	return bEnabled;
}

String
TrackSQL::getEndOfSessionEmailMsg(int32     notificationID,
                                  SESSIONID sessionID,
                                  int32*    msglen,
								  String&   nameFrom,
                                  String&   emailFrom,
                                  String&   emailTo,
                                  String&   subject)
{
	ODBCConnection* conn;
	ODBCQuery* query;
	String result;
	String sess_startDate;
	String sess_endDate;
	String sess_login;
	String sess_pid;
	String sess_playerclass;
	String sess_IP;

	uint8 sess_forMoney = 0;
	int32 sess_startBalance=0, sess_endBalance=0, sess_totalGames=0, sess_totalBets=0, sess_netWin=0;

	bool8 srcDestInfoOK = false;
	bool8 sessionInfoOK = false;

	*msglen = 0;

	conn = getConn();
	if (!conn)
    {
		return result;
    }

	srcDestInfoOK = getSystemEmailRouting(conn, notificationID, nameFrom, emailFrom, emailTo, subject);

    if ( srcDestInfoOK || (emailTo.find("@") != String::NPOS) || (emailFrom.find("@") != String::NPOS) )
	{
		query = conn->query();
		if (query)
		{
			query->define("exec pub_GetPlayerSessionInfo ");
			query->addParam(sessionID, ODBCQuery::NOQUOTES);

			if (query->exec())
			{
				if (query->getRow())
				{
					sessionInfoOK = true;

					sessionInfoOK &= query->getData(1, sess_startDate);
					sessionInfoOK &= query->getData(2, sess_endDate);
					sessionInfoOK &= query->getData(3, sess_pid);
					sessionInfoOK &= query->getData(4, &sess_forMoney);
					sessionInfoOK &= query->getData(5, sess_IP);
					sessionInfoOK &= query->getData(6, &sess_startBalance, ODBCQuery::MONEY);
					sessionInfoOK &= query->getData(7, &sess_endBalance, ODBCQuery::MONEY);
					sessionInfoOK &= query->getData(8, &sess_totalGames, ODBCQuery::MONEY);
					sessionInfoOK &= query->getData(9, &sess_totalBets, ODBCQuery::MONEY);
					sessionInfoOK &= query->getData(10, &sess_netWin, ODBCQuery::MONEY);
					sessionInfoOK &= query->getData(11, sess_playerclass);
					sessionInfoOK &= query->getData(12, sess_login);
				}
			}

			delete query;
		}

	}
	delete conn;

	if (srcDestInfoOK &&
		sessionInfoOK &&
		sess_totalGames)	//only send e-mail when they have played games
	{
		// Append login name to subject
        subject += TEXT(" (PID:");
        subject += sess_pid;
        subject += TEXT(")");

        // Build result message
        result.sprintf(TEXT("Login: %s\r\n")
			TEXT("Player ID: %s\r\n")
            TEXT("Player Class: %s\r\n")
            TEXT("Session ID: %S\r\n")	// char*
            TEXT("For Money: %s\r\n")
            TEXT("IP Address: %s\r\n")
            TEXT("Start Date: %s\r\n")
            TEXT("End Date: %s\r\n")
            TEXT("Starting Balance: %0.2f\r\n")
            TEXT("Ending Balance: %0.2f\r\n")
            TEXT("Total Games: %ld\r\n")
            TEXT("Total Bets: %0.2f\r\n")
            TEXT("Net Win: %0.2f\r\n"),
			(const wchar_t*)sess_login,
			(const wchar_t*)sess_pid,
            (const wchar_t*)sess_playerclass,
            sessionID,
            sess_forMoney ? TEXT("Yes") : TEXT("No"),
            (const wchar_t*)sess_IP,
            (const wchar_t*)sess_startDate,
            (const wchar_t*)sess_endDate,
            (double)sess_startBalance/100,
            (double)sess_endBalance/100,
            sess_totalGames,
            (double)sess_totalBets/100,
            (double)sess_netWin/100);
	}

	return result;
}

void
TrackSQL::addBadPacket(int32 gameid, uint8 machid, const String& error_reason, int32 severity, const PID& pid, char MessageType, uint8* msgbuf, int32 msglength)
{
	ODBCConnection* conn;
	ODBCQuery* query;

	conn = getConn();
	if (!conn)
		return;

	query = conn->query();
	if (query)
	{
		query->define("exec pub_AddBadPacket ");
		query->addParam(gameid);
		query->addParam(machid, ODBCQuery::BINARY);
		query->addParam(error_reason);
		query->addParam(severity);
		query->addParam(pid);
        query->addParam(String(String::Character(MessageType)));
		query->addParam((uint8*)msgbuf, msglength, ODBCQuery::BINARY);

		if (query->exec())
		{
			while (query->getRow())
				/* ignore results */ ;
		}
		delete query;
	}
	delete conn;
}


int32
TrackSQL::getEmailAddress(int32 casinoId, const PID& pid,
	char* email, int32 maxEmailInclNull)
{
	ODBCConnection* conn;
	ODBCQuery* query;
	bool8 ok = false;

	*email = '\0';

	conn = getConn();
	if (!conn)
		return NoConnection;

	query = conn->query();
	if (query)
	{
		query->define("exec pub_GetAccountInfoByPID ");
		query->addParam(casinoId);
		query->addParam(pid);

		if (query->exec())
		{
			while (query->getRow())
				ok = query->getData(24, email, maxEmailInclNull);
		}

		delete query;
	}
	delete conn;

    return ok ? NoError : ExecFailed;
}

int32
TrackSQL::getCustomFeatures(uint8 * mobile, String * affSubmitURL,
	String * endOfSessionURL, uint8 * playhistoryDisabled)
{
	ODBCConnection* conn;
	ODBCQuery* query;
	bool8 ok = false;
	bool8 result = true;
	bool8 isNull = false;

	conn = getConn();
	if (!conn)
		return NoConnection;

	query = conn->query();
	if (query)
	{
		query->define("exec pub_getCustomFeatures");
		if (query->exec())
		{
			if (query->getRow())
			{
				if (mobile)
					result &= query->getData(1, mobile);

				if (affSubmitURL)
					result &= query->getData(2, affSubmitURL);

				if (endOfSessionURL)
					result &= query->getData(3, endOfSessionURL);

				if (playhistoryDisabled)
				{
					if (query->getData(4, playhistoryDisabled, &isNull))
					{
						// Null condition means history is available.
						// Normalize database data to boolean style result.
						*playhistoryDisabled = (isNull) ? 0 : (uint8)(*playhistoryDisabled != 0);

						result &= true;
					}
					else
						result = false;
				}

				ok = result;
			}
		}

		delete query;
	}

	delete conn;

    return ok ? NoError : ExecFailed;
}


//////////////////////////////////////////////////////////////////////////////
// getAccountInfo
//
// Get full info on the account.
//////////////////////////////////////////////////////////////////////////////
bool8
TrackSQL::getAccountInfo( int32 casinoId, const String& inlogin, AccountInfo *pInfo  )
{
	ODBCConnection* conn;
	ODBCQuery* query;
	int32 error;
    bool bRetVal = false;
	String login = inlogin;

    // Get connection
	conn = getConn();
	if (conn)
    {
        // Convert login to lower case
        login.toLower();

        // Get Query
        error = ExecFailed;
	    query = conn->query();
	    if ( query )
	    {
            query->define("exec pub_GetAccountInfoByLogin ");
		    query->addParam(casinoId);
		    query->addParam(login);

            // Execute Query
            if ( query->exec() )
		    {
    			if ( query->getRow() )
                {
					bool8 bOK = query->getData(3,  pInfo->pid);
                    bOK = bOK & query->getData(6,  pInfo->bankAcctNum);
			        bOK = bOK & query->getData(7,  pInfo->password);
                    bOK = bOK & query->getData(16, pInfo->firstName);
                    bOK = bOK & query->getData(17, pInfo->lastName);
                    bOK = bOK & query->getData(18, pInfo->addr1);
                    bOK = bOK & query->getData(19, pInfo->addr2);
                    bOK = bOK & query->getData(20, pInfo->city);
                    bOK = bOK & query->getData(21, pInfo->state);
                    bOK = bOK & query->getData(22, pInfo->zip);
                    bOK = bOK & query->getData(23, pInfo->country);
                    bOK = bOK & query->getData(24, pInfo->email);
                    bOK = bOK & query->getData(25, pInfo->dayphone);
                    bOK = bOK & query->getData(26, pInfo->homephone);
                    bOK = bOK & query->getData(32, pInfo->login);

                    // Return true if there were no errors
                    if( bOK )
                    {
                        bRetVal = true;
                    }
                }
            }

			delete query;
        }

		delete conn;
    }

    return bRetVal;
}

bool8
TrackSQL::isGameEnabled(int32 gameId, uint8 machId)
{
	ODBCConnection* conn;
	ODBCQuery* query;
	int32 error;
	int32 enabled = 0;

    // Get connection
	conn = getConn();
	if (conn)
    {
        // Get Query
        error = ExecFailed;
	    query = conn->query();
	    if ( query )
	    {
            query->define("exec pub_GetIsGameEnabled ");
		    query->addParam(gameId);
		    query->addParam(machId);

            // Execute Query
            if ( query->exec() )
		    {
    			if ( query->getRow() )
                {
					query->getData(1, &enabled);
                }
            }

			delete query;
        }

		delete conn;
    }

    return enabled ? NoError : ExecFailed;
}

// CSN-7075: New Authentication
bool8
TrackSQL::createRTGSession(bool8 forMoney, const String& login, SESSIONID sessionID, String ClientID)
{
	ODBCConnection* conn;
	ODBCQuery* query;
	bool8 ok = false;
	
	conn = getConn();
	if (!conn)
		return NoConnection;

	query = conn->query();
	if (query)
	{
		query->define("exec pub_Create_RTG_Session_ClientCode ");
		query->addParam(ServerOpts::serverId);
		query->addParam(ServerOpts::casinoId);
		query->addParam(ServerOpts::skinId);
		query->addParam(login);
		query->addParam(forMoney);
		query->addParam(ClientID);		

		if (query->exec())
		{
			uint8 i = 0;

			while (query->getRow())
			{
				if (i++ == 0 && query->getData(2, sessionID, MAXSESSIONIDLEN))
				{
					ok = true;
				}
			}
		}
		delete query;
	}
	delete conn;

	return ok;
}

void TrackSQL::logout(int32 casinoId, const PID& pid, bool8 forMoney, const String& IPAddress, SESSIONID sessionID)
{
	// CSN-11525: If no session, nothing to logout
	if (strlen(sessionID) > 0)
	{
		ODBCConnection* conn;
		ODBCQuery* query;

		conn = getConn();
		if (!conn)
			return;

		query = conn->query();
		if (query)
		{
			query->define("exec pub_Logout ");
			query->addParam(casinoId);
			query->addParam(pid);
			query->addParam((bool8)(forMoney != 0));
			query->addParam(IPAddress);
			query->addParam(sessionID, ODBCQuery::NOQUOTES);

			query->exec();
			delete query;
		}
		delete conn;
	}
}

// CSN-7076: New Authentication (fun play)
bool8 TrackSQL::getAvailableFunID( String& sFunID )
{
    bool8 bRetVal = false;

    ODBCConnection* conn;
	ODBCQuery* query;
    	
	conn = getConn();
	if (conn)
	{
		query = conn->query();
		if (query)
		{
			query->define( TEXT("exec pub_getAvailableFunPID ") );

			if ( query->exec() )
			{
				if ( query->getRow() )
				{
					query->getData( 1, &sFunID );

                    bRetVal = true;
				}
			}
			delete query;
		}
		delete conn;
	}

	return bRetVal;
}

#ifdef DEBUGSPIN
bool8 TrackSQL::isFreeFromAuthentication(String pid)
{
	bool8 bResult = false;

	ODBCConnection* conn;
	ODBCQuery* query;

	conn = getConn();
	if (conn)
	{
		query = conn->query();
		if (query)
		{
			query->define(TEXT("exec pub_isPIDFreeFromAuth "));
			query->addParam(pid);
						
			if (query->exec())
			{
				if (query->getRow())
				{
					query->getData(1, &bResult);
				}
			}
			delete query;
		}
		delete conn;
	}

	return bResult;
}
#endif